package educrypt.tests;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import educrypt.analysis.Frequencies;
import educrypt.analysis.FrequencyAnalysis;
import educrypt.ciphers.Caesar;
import educrypt.ciphers.Vigenere;
import educrypt.ciphers.hill.Hill;
import educrypt.ciphers.playfair.Playfair;
import educrypt.commons.Alphabet;
import educrypt.commons.Text;
import educrypt.cryptanalysis.FrequencyBasedCryptAnalysis;
import educrypt.cryptanalysis.vigenere.CryptAnalysisVigenere;
import educrypt.database.dao.FrequencyAnalysisDAO;
import educrypt.database.dao.TextLanguageDAO;
import educrypt.database.dao.TextTypeDAO;
import educrypt.exceptions.EduCryptException;
import educrypt.io.Input;

@SuppressWarnings("unused")
public class Tester {

	/**
	 * @param args
	 */

	private static final String TEXTPATH = "testFiles/Don Quijote.txt";
	private static final Alphabet abc = new Alphabet("abc",
			"abcdefghijklmnñopqrstuvwxyz");
	private static final Text text = createText(TEXTPATH);

	private static Text createText(String path) {
		Text text = new Text();
		try {
			text.setContent(Input.readTextFromFile(path));
		} catch (EduCryptException e) {
			e.printStackTrace();
		}
		text.setName(path.substring(path.lastIndexOf("/")));
		text.setLanguage("Español");
		text.setType("Científico");
		return text;
	}

	/* -- TESTs -- */
	// private static void testFullRead() {
	// byte[] inputData = null;
	// try {
	// inputData = Input.readFile("testIO/testPDF.pdf");
	// } catch (EduCryptException e) {
	// e.printStackTrace();
	// }
	// char[] characters = Util.byteArrayToCharArray(inputData);
	// // String st = Util.charArrayToString(characters);
	// String st = new String(characters);
	// System.out.println(st);
	// characters = st.toCharArray();
	// // System.out.println(st);
	// byte[] outputData = Util.charArrayToByteArray(characters);
	// Output.writeFile(outputData, "output.pdf");
	// }

	// private static void testFullRead2() {
	// try {
	// String text = Input.readWholeFile(Input
	// .readFile("testIO/testPDF.pdf"));
	// System.out.println(text);
	// } catch (EduCryptException e) {
	//
	// e.printStackTrace();
	// }
	// }

	private static Frequencies testAnalisys() {
		long startTime = System.currentTimeMillis();
		FrequencyAnalysis analysis = new FrequencyAnalysis(text, abc, 1);
		Frequencies fq = analysis.getFrequencies();
		FrequencyAnalysisDAO analysisDAO = FrequencyAnalysisDAO.getInstance();
		analysisDAO.create(analysis);
		System.out.println("ANALYSIS FREQUENCIES\n" + fq);
		System.out.println((System.currentTimeMillis() - startTime)
				/ (double) 1000);
		return fq;
	}

	private static Frequencies testAverageFrequencies()
			throws EduCryptException {
		FrequencyAnalysisDAO analysisDAO = FrequencyAnalysisDAO.getInstance();
		Frequencies fq = analysisDAO.getAverageFrequencies(abc.getName(), 2,
				text.getLanguage(), text.getType());
		System.out.println("AVERAGE FREQUENCIES\n" + fq);
		return fq;
	}

	private static void testCaesar() {
		long startTime = System.currentTimeMillis();
		Caesar caesarCipher = new Caesar(abc, 15);
		Text cipherText = caesarCipher.encode(text);
		System.out.println(cipherText.getContent());
		try {
			PrintWriter pw = new PrintWriter(new FileWriter(
					"testFiles/caesar.txt"));
			pw.write(cipherText.getContent());
		} catch (IOException e) {
			e.printStackTrace();
		}
		Text plainText = caesarCipher.decode(cipherText);
		System.out.println(plainText.getContent());
		System.out.println((System.currentTimeMillis() - startTime)
				/ (double) 1000);
	}

	private static void testVigenere() {
		Vigenere vigenereCipher = new Vigenere(abc, "hellowor");
		Text cipherText = vigenereCipher.encode(text);
		System.out.println(cipherText.getContent());
		try {
			PrintWriter pw = new PrintWriter(new FileWriter(
					"testFiles/vigenere.txt"));
			pw.write(cipherText.getContent());
		} catch (IOException e) {
			e.printStackTrace();
		}

		Text plainText = vigenereCipher.decode(cipherText);
		System.out.println(plainText.getContent());
	}

	private static void testPlayfair() {
		final String PF_ALPHABET = "abcdefghijklmnoprstuvwxyz";
		// Playfair playfairCipher = new Playfair(Playfair.ALPHABET, "hola");
		Playfair playfairCipher = new Playfair(
				new Alphabet("bla", PF_ALPHABET),
				Alphabet.formatSymbols("PLAYFIREXAMPLE"));
		Text cipherText = playfairCipher
				.encode(createText("testFiles/prueba.txt"));

		System.out.println(cipherText.getContent());

		// try {
		// PrintWriter pw = new PrintWriter(new FileWriter(
		// "testFiles/playfair.txt"));
		// pw.write(cipherText.getContent());
		// } catch (IOException e) {
		// e.printStackTrace();
		// }

		Text plainText = playfairCipher.decode(cipherText);
		System.out.println(plainText.getContent());
		// if
		// (cipherText.getContent().equals("Bmod zbx dnab ek udm uixmm ouvif"))
		// {
		// System.out.println("---Playfair encription passed---");
		// }
	}

	private static void testHill() throws EduCryptException {
		// String correctKeyword =
		// educrypt.ciphers.hill.Hill.formatKeyword("GYBNQKURP", abc);
		// System.out.println(correctKeyword);
		Alphabet abcHill = new Alphabet("hill", "abcdefghijklmnopqrstuvwxyz");
		Hill hillCipher = new Hill(abcHill, "GYBNQKURP");
		Text cipherText = hillCipher.encode(new Text("ACTAbCd"));
		System.out.println(cipherText.getContent());
		Text plainText = hillCipher.decode(cipherText);
		System.out.println(plainText.getContent());
	}

	private static void testCaesarBreak() throws EduCryptException {
		Text cipherText = createText("testFiles/Don QuijoteReduced - Caesar 15_2.txt");
		cipherText.setType("Literario");
		cipherText.setLanguage("Español");
		Alphabet alphabet = new Alphabet("abcEspañol",
				"abcdefghijklmnñopqrstuvwxyz");
		FrequencyAnalysis analysisCipherText = new FrequencyAnalysis(
				cipherText, alphabet, 1);
		FrequencyAnalysisDAO analysisDAO = FrequencyAnalysisDAO.getInstance();

		Frequencies cipherTextFrequencies = analysisCipherText.getFrequencies();
		Frequencies averageFrequencies = analysisDAO.getAverageFrequencies(
				alphabet.getName(), 1, cipherText.getLanguage(),
				cipherText.getType());

		if (cipherTextFrequencies.getMaxNumberOfSamePercentageOcurrences() > 4) {
			throw new EduCryptException("Texto demasiado pequeño");
		}

		FrequencyBasedCryptAnalysis cryptoAnalysis = new FrequencyBasedCryptAnalysis(
				cipherTextFrequencies, averageFrequencies);
		List<Integer> sortedOffsets = cryptoAnalysis
				.getSortedOffsetsFromCaesarCandidateKeys(cryptoAnalysis
						.cryptAnalyze());
		int offset = sortedOffsets.get(0);

		System.out.println(offset);
		// Caesar caesarCipher = new Caesar(abc, offset);
		// Text decodedText = caesarCipher.decode(cipherText);
		// System.out.println(decodedText.getContent());
	}

	private static void testVigenereBreak() throws EduCryptException {
		Text cipherText = createText("testFiles/Don QuijoteReduced - VigenereHELLOWOR.txt");
		CryptAnalysisVigenere cryptAnalysis = new CryptAnalysisVigenere(
				cipherText, abc);
		List<Integer> offsets = cryptAnalysis.cryptAnalyze();
		Vigenere vigenereCipher = new Vigenere(abc, offsets);
		System.out.println(vigenereCipher.decode(cipherText).getContent());
	}

	// private static void testPlayfairBreak() throws CipherException {
	// // CUIDADO! El alfabeto de playfair debe estar definido en la bd
	// Alphabet playfairAlphabet = Playfair.ALPHABET;
	// Text cipherText =
	// createText("testFiles/Don QuijoteReduced - Playfair.txt");
	// FrequencyAnalysis analysisCipherText = new FrequencyAnalysis(
	// cipherText, playfairAlphabet, 2);
	// FrequencyAnalysisDAO analysisDAO = FrequencyAnalysisDAO.getInstance();
	//
	// Frequencies cipherTextFrequencies = analysisCipherText.getFrequencies();
	// Frequencies averageFrequencies = analysisDAO.getAverageFrequencies(
	// Playfair.ALPHABET.getName(), 2, cipherText.getLanguage(),
	// cipherText.getType());
	//
	// // if (cipherTextFrequencies.getMaxNumberOfPercentageOcurrences() > 4) {
	// // throw new CipherException("Texto demasiado pequeño");
	// // }
	//
	// FrequencyBasedCryptAnalysis cryptoAnalysis = new
	// FrequencyBasedCryptAnalysis(
	// cipherTextFrequencies, averageFrequencies);
	// List<Integer> sortedOffsets = cryptoAnalysis
	// .getSortedOffsetsFromCaesarCandidateKeys(cryptoAnalysis
	// .cryptAnalyze());
	// int offset = sortedOffsets.get(0);
	//
	// System.out.println(offset);
	//
	// // Playfair.ALPHABET;
	// }

	private static void testInsertTextLanguageAndTextType() {
		TextLanguageDAO textLanguageDAO = TextLanguageDAO.getInstance();
		textLanguageDAO.create("Español");
		textLanguageDAO.create("Inglés");
		TextTypeDAO textTypeDAO = TextTypeDAO.getInstance();
		textTypeDAO.create("Literario");
		textTypeDAO.create("Científico");
	}

	public static void main(String[] args) throws EduCryptException {
		// testInsertTextLanguageAndTextType();
		// testInsertAlphabet();
		// testAnalisys();
		// testAverageFrequencies();
		// testFullRead();
		// testCaesar();
		// testVigenere();
		testPlayfair();
		// testHill();
		// testInputPDF();
		// testInputDoc();
		// testInputDocX();
		// testInputAnyDoc();
		// testCaesarBreak();
		// testVigenereBreak();
		// testPlayfairBreak();
	}
}
